#include "MusicTrack.h"

TMusicTrack::TMusicTrack()
{
}

MusicTrack::MusicTrack(const std::string& ArtistName, const std::string& SongName, const std::string& WebAdress)
: m_ArtistName(ArtistName), m_SongName(SongName), m_WebAdress(WebAdress)
{
}

void MusicTrack::Output(void)
{
	cout << ArtistName << "	" << SongName << endl;
}

void MusicTrack::Download(void)
{
 	using boost::asio::ip::tcp;
	string::size_type pos_first, pos_last;
	string directory;
		// Server name
	try 
	{
		boost::asio::io_service io_service;
			
	    tcp::resolver resolver(io_service);

		pos_first = WebAdress.find(".");
		pos_first = WebAdress.find("/", pos_first + 1);
		directory = WebAdress.substr(WebAdress.find("cs"), pos_first - WebAdress.find("cs"));
			// Gets the server name from the full link to the file
		tcp::resolver::query query(directory, "http");
		tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
		tcp::resolver::iterator end;
			// Creating a resolver (DNS - client)

	    tcp::socket socket(io_service);
			// Creating socket (works like a stream) 
	    boost::system::error_code error = boost::asio::error::host_not_found;

		while (error && endpoint_iterator != end)
		{
		 socket.close();
	      socket.connect(*endpoint_iterator++, error);
	    }	
			// Trying to connect
		if (error)
			throw boost::system::system_error(error);
			// If not connected, throw exception

		boost::asio::streambuf request;
			// Stream buffer for request
		std::ostream request_stream(&request);
			// Creating std::ostream over boost::asio::streambuf for requesting
		
		request_stream << "GET " << WebAdress.substr( WebAdress.find("/u"), WebAdress.size() - WebAdress.find("/u") ) << " HTTP/1.1\r\n";
		request_stream << "Host: " << directory << "\r\n";
		request_stream << "Accept: */*\r\n";
		request_stream << "User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)\r\n";
		request_stream << "Referer: http://vkontakte.ru/\r\n\r\n";
			// Forming the request

		boost::asio::write(socket, request);
			// Sending the request (writing to the socket)
		boost::asio::streambuf response;
		boost::asio::read_until(socket, response, "\r\n");
			// Reading first line from response

		std::istream response_stream(&response);
			// Creating std::istream over boost::asio::streambuf for responsing
		std::string http_version;
		response_stream >> http_version;
		unsigned int status_code;
		response_stream >> status_code;
		std::string status_message;
		std::getline(response_stream, status_message);
			// Reading first line from response_stream
		if (!response_stream || http_version.substr(0, 5) != "HTTP/")
		{
			std::cout << "Invalid response\n";
			return ;
		}
			// Halt if no response or not HTTP-style response
		if (status_code != 200)
		{
		  std::cout << "Response returned with status code " << status_code << "\n";
		  return ;
		}
			// Halt if server doesn't supports the request (status_code = 200)
		boost::asio::read_until(socket, response, "\r\n\r\n");
			// Reading headers (to the begining of content) to response stream
		std::string header;
		while (std::getline(response_stream, header) && header != "\r")
		{
			//cout << header;
		};
			// Processing the header (if needed)

		//boost::filesystem::create_directory("downloads");
		//if (response.size() > 0)
		 // std::cout << &response;
		if ( !boost::filesystem::exists( "downloads/" ) )
			boost::filesystem::create_directory("downloads");
			// Creating the download directory if not exists
		string filename("downloads/"+ArtistName+"-"+SongName+".mp3");
			// Forming the filename
		ofstream file(filename.data(), ios::out | ios::binary);
			// Creating binary file stream 
		while (boost::asio::read(socket, response,
			  boost::asio::transfer_at_least(1), error))
		{
			file << &response;
		};
			// Writing to file binary data
		file.close();
			// 
		if (error != boost::asio::error::eof)
		  throw boost::system::system_error(error);
	  }
	  catch (std::exception& e)
	  {
		std::cout << "Exception: " << e.what() << "\n";
	  }
	  return ;	
}

TMusicTrack::~TMusicTrack(void)
{
}
